package com.myhome.service.impl;

import com.alibaba.fastjson.JSON;
import com.myhome.domain.User;
import com.myhome.feign.FeignClientConfig;
import com.myhome.feign.JwtToken;
import com.myhome.geetest.GeetestLib;
import com.myhome.geetest.GeetestLibResult;
import com.myhome.model.LoginForm;
import com.myhome.model.LoginResult;
import com.myhome.service.MemberLoginService;
import com.myhome.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Author QYiXin
 * @Date 2021 10 14 16 21
 **/
@Service
@Slf4j
public class MemberLoginServiceImpl implements MemberLoginService {
    @Autowired
    FeignClientConfig feignClientConfig;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    GeetestLib geetestLib;
    @Autowired
    UserService userService;
    //e10adc3949ba59abbe56e057f20f883e
    @Override
    public LoginResult login(LoginForm loginForm) throws UnknownHostException {
        checkLoginFormData(loginForm);
        System.out.println("名字= "+loginForm.getUsername());
        System.out.println("密码= "+loginForm.getPassword());
        LoginResult result = null;
        ResponseEntity<JwtToken> token = feignClientConfig.getToken("password", loginForm.getUsername(), loginForm.getPassword(), "memberLogin", "Basic Y2xpZW50OjExMTExMQ==");
        if (token.getStatusCode() == HttpStatus.OK) {
            result = new LoginResult();
            JwtToken jwtBody = token.getBody();
            System.out.println("type: "+jwtBody.getTokenType());
            result.setAccess_token(jwtBody.getTokenType()+" "+jwtBody.getAccessToken());
            result.setRefresh_token(jwtBody.getRefreshToken());
            result.setExpire(Long.valueOf(jwtBody.getExpiresIn()));
            User user = userService.getUserByMobileOrEmail(loginForm.getUsername());
            result.setUsername(user.getUsername());
            redisTemplate.opsForValue().set(jwtBody.getAccessToken(), "",Long.valueOf(jwtBody.getExpiresIn()), TimeUnit.SECONDS);
        }
        return result;
    }

    private void checkLoginFormData(LoginForm loginForm) throws UnknownHostException {
        String challenge = loginForm.getGeetest_challenge();
        String validate = loginForm.getGeetest_validate();
        String seccode = loginForm.getGeetest_seccode();
        int status = 0;
        String userId = "";
        // session必须取出值，若取不出值，直接当做异常退出
        String statusStr = redisTemplate.opsForValue().get(GeetestLib.GEETEST_SERVER_STATUS_SESSION_KEY+":"+loginForm.getUuid()).toString();
        status = Integer.valueOf(statusStr).intValue();
        userId = redisTemplate.opsForValue().get(GeetestLib.GEETEST_SERVER_USER_KEY + ":" + loginForm.getUuid()).toString();
        GeetestLibResult result = null;
        if (status == 1) {
            /*
            自定义参数,可选择添加
                user_id 客户端用户的唯一标识，确定用户的唯一性；作用于提供进阶数据分析服务，可在register和validate接口传入，不传入也不影响验证服务的使用；若担心用户信息风险，可作预处理(如哈希处理)再提供到极验
                client_type 客户端类型，web：电脑上的浏览器；h5：手机上的浏览器，包括移动应用内完全内置的web_view；native：通过原生sdk植入app应用的方式；unknown：未知
                ip_address 客户端请求sdk服务器的ip地址
            */
            Map<String, String> paramMap = new HashMap<String, String>();
            paramMap.put("user_id", userId);
            paramMap.put("client_type", "web");
            ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            paramMap.put("ip_address", InetAddress.getLocalHost().getHostAddress());
            result = geetestLib.successValidate(challenge, validate, seccode, paramMap);
            log.info("验证的结果为{}", JSON.toJSONString(result));
        } else {
            result = geetestLib.failValidate(challenge, validate, seccode);
        }
        if(result.getStatus()!=1){
            log.error("验证异常",JSON.toJSONString(result,true));
            throw new IllegalArgumentException("验证码验证异常") ;
        }

    }

    public static void main(String[] args) {
        String s = Base64.getEncoder().encodeToString("123456".getBytes(StandardCharsets.UTF_8));
        System.out.println(s);
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        String e = encoder.encode("e10adc3949ba59abbe56e057f20f883e");
        System.out.println(e);
    }
}

